home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 1
/
Nebula One.iso
/
Utilities
/
Workspace
/
Background3.2
/
Source
/
background
/
Background.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
11KB
|
491 lines
//
#import <math.h>
#include <sys/stat.h>
#import "Background.h"
#import <dpsclient/wraps.h>
#import <appkit/Application.h>
#import <objc/hashtable.h>
#import <defaults/defaults.h>
#import "PSsplat.h"
#import <appkit/OpenPanel.h>
#import <appkit/Control.h>
#import <appkit/Menu.h>
#import <appkit/MenuCell.h>
#import <appkit/Matrix.h>
#import <appkit/nextstd.h>
#define PSsplat( r, p) _PSsplat( (r)->origin.x, (r)->origin.y, \
(r)->size.width, (r)->size.height, (p)->x, (p)->y)
//
@implementation Background:View
//
//
void handler(DPSTimedEntry teNumber, double now, id background)
{
[background next:nil];
}
- initFrame:(const NXRect *)frameRect
{
char *d,*f;
int len;
[super initFrame:frameRect];
imageNames = NULL;
imageTimes = NULL;
images = NULL;
imageCount = 0;
max = 0;
current = 0;
d = getenv("HOME"); if (!d) d="";
f = ".background";
len = strlen(d) + 1 + strlen(f) + 1;
defaultfile = NX_ZONEMALLOC([self zone], defaultfile, char, len);
strcpy(defaultfile, d);
strcat(defaultfile,"/");
strcat(defaultfile,f);
timer = NULL;
repeat = 600;
permanent = NO;
updateMenu = YES;
return self;
}
- reset
{
int i;
for (i=0; i<imageCount; i++) {
NXZoneFree([self zone], imageNames[i]);
if(images[i]) [images[i] free];
}
if (imageCount) {
NXZoneFree([self zone], imageNames);
NXZoneFree([self zone], imageTimes);
NXZoneFree([self zone], images);
}
imageCount=0;
current=0;
return self;
}
- free
{
[self reset];
if (timer) DPSRemoveTimedEntry(timer);
return [super free];
}
//
- loadImageNamed:(const char *)aName
{
// printf("Loading %s.\n", aName);
if ([self getImage:aName]<0) return nil;
return self;
}
- setImageNamed:(const char *)aName
{
int i;
i = [self getImage:aName];
if (i>=0) [self setImage:i]; else return nil;
return self;
}
- setRepeatValue:(float)r
{
char str[7];
repeat = r;
if (timer) DPSRemoveTimedEntry(timer);
if (repeat<1) {
strcpy(str,"off");
timer=NULL;
} else {
if (r<60) sprintf(str,"%2ds",(int)r);
else if (r<3600) sprintf(str,"%2dmin",(int)(r/60));
else sprintf(str,"%2dh",(int)(r/3600));
timer = DPSAddTimedEntry(repeat,
(DPSTimedEntryProc)handler, self, NX_BASETHRESHOLD);
}
[repeatText setStringValue:str];
[repeatSlider setFloatValue:log(r+1)/12];
// printf("Setting repeat to %s.\n", str);
[self writeDefault];
return self;
}
- setRepeatText:aText
{
repeatText = aText;
return self;
}
- setRepeatSlider:aSlider
{
repeatSlider = aSlider;
return self;
}
- setPermanent:(BOOL)flag
{
permanent = flag;
return self;
}
//
// target/action
//
- open:sender
{
OpenPanel *op=[OpenPanel new];
char *types[]={ "tiff", "eps", NULL};
char *directory, *filename, *fn;
const char *d;
const char * const *files;
int l, len, ind;
if( !imageCount)
{
directory=getenv( "HOME");
if( !directory) directory="/";
filename=NXCopyStringBufferFromZone("", [self zone]);
} else {
fn=NXCopyStringBufferFromZone(imageNames[current], [self zone]);
if (filename=rindex(fn, '/')) *filename++='\0', directory=fn;
else
{
filename=imageNames[current];
directory=getenv( "HOME");
if( !directory) directory="/";
}
}
ind = current;
[op allowMultipleFiles:YES];
if( [op runModalForDirectory:directory file:filename types:types]) {
len = 0;
for (files=[op filenames]; *files; files++) if ((l=strlen(*files))>len) len=l;
len += strlen(d=[op directory])+2;
NX_ZONEMALLOC([self zone], fn, char, len);
strcpy(fn,d);
strcat(fn,"/");
filename=rindex(fn, '/')+1;
for (files=[op filenames]; *files; files++) {
strcpy(filename,*files);
if ((l=[self getImage:fn])>0) ind = l;
}
}
[self setImage:ind];
[self writeDefault];
return self;
}
- next:sender
{
if (++current>=imageCount) current=0;
[self setImage:current];
return self;
}
- resize:sender
{
char *p;
p = imageNames[current];
if (p[0]=='*') {
NX_ZONEMALLOC([self zone], imageNames[current], char, strlen(p));
strcpy(imageNames[current], p+1);
NXZoneFree([self zone], p);
[images[current] free];
images[current]=nil;
} else {
NX_ZONEMALLOC([self zone], imageNames[current], char, strlen(p)+2);
strcpy(imageNames[current],"*");
strcat(imageNames[current],p);
NXZoneFree([self zone], p);
}
[self resizeImage:current];
[self setImage:current];
[self writeDefault];
return self;
}
- previous:sender
{
if (--current<0) current=imageCount-1;
[self setImage:current];
return self;
}
- redraw:sender
{
[self display];
return self;
}
- select:sender
{
sender = [sender selectedCell];
updateMenu=NO;
[self setImageNamed:[sender title]];
updateMenu=YES;
return self;
}
- toFront:sender
{
PSsetwindowlevel( NX_DOCKLEVEL+1, [window windowNum]);
[window orderFront:sender];
[window addToEventMask:NX_MOUSEDOWNMASK];
return self;
}
- toTop:sender
{
int i;
char *n;
time_t t;
id img;
n = imageNames[current];
t = imageTimes[current];
img = images[current];
for (i=current; i>0; i--) {
imageNames[i] = imageNames[i-1];
imageTimes[i] = imageTimes[i-1];
images[i] = images[i-1];
}
imageNames[0] = n;
imageTimes[0] = t;
images[0] = img;
current = 0;
[self setImage:current];
[self writeDefault];
return self;
}
- delete:sender
{
int i;
for (i=current; i<imageCount; i++) {
imageNames[i] = imageNames[i+1];
imageTimes[i] = imageTimes[i+1];
images[i] = images[i+1];
}
imageCount--;
if (current>=imageCount && current>0) current--;
[self setImage:current];
[self writeDefault];
return self;
}
- deleteAll:sender
{
[self reset];
[self setImage:current];
return self;
}
- takeRepeatValueFrom:sender
{
[self setRepeatValue:exp(12*[sender floatValue])-1];
return self;
}
///
/// Menu generation
///
- setMenu:aMenuCell
{
menu = [aMenuCell target];
[self updateMenu];
return self;
}
- updateMenu
{
id cell;
id matrix;
int i;
if (!updateMenu) return self;
matrix = [menu itemList];
while([matrix cellCount]) [matrix removeRowAt:0 andFree:YES];
[menu setItemList:matrix];
for (i=0; i<imageCount; i++) {
cell = [menu addItem:imageNames[i] action:@selector(select:) keyEquivalent:0];
[cell setTarget:self];
}
[menu display];
return self;
}
//
// private:
//
- (int)getImage:(const char *)aName
{
int i;
if (aName==NULL) return -1;
for (i=0; i<imageCount; i++) if (strcmp(aName, imageNames[i])==0) break;
if (i>=imageCount) {
if (++imageCount>max) {
if (!max) {
imageNames = NX_ZONEMALLOC([self zone], imageNames, char *, 1);
imageTimes = NX_ZONEMALLOC([self zone], imageTimes, time_t, 1);
images = NX_ZONEMALLOC([self zone], images, NXImage *, 1);
max = 1;
} else {
max *= 2;
imageNames = NX_ZONEREALLOC([self zone], imageNames, char *, max);
imageTimes = NX_ZONEREALLOC([self zone], imageTimes, time_t, max);
images = NX_ZONEREALLOC([self zone], images, NXImage *, max);
}
}
imageNames[i]=NXCopyStringBufferFromZone(aName, [self zone]);
images[i] = nil;
}
return i;
}
- setImage:(int)i
{
struct stat sb;
char *p;
int flag;
if (i>=0 && i<imageCount) {
if (imageNames[i][0]=='*') p=imageNames[i]+1; else p=imageNames[i];
flag = stat(p, &sb);
if (!images[i] || (flag==0 && imageTimes[i]<sb.st_mtime)) {
images[i]=[[NXImage allocFromZone:[self zone]] initFromFile:p];
imageTimes[i]=sb.st_mtime;
if (imageNames[i][0]=='*') [self resizeImage:i];
}
current = i;
}
[self updateMenu];
[self display];
return self;
}
- resizeImage:(int)i
{
const NXScreen *screen;
NXSize size;
if (i>=0 && i<imageCount && images[i]) {
screen = [window screen];
size = screen->screenBounds.size;
[images[i] setScalable:YES];
[images[i] setSize:&size];
}
return self;
}
//
// read and write defaults
//
- readDefault
{
char p[256], f[256];
NXStream *s;
FILE *temp;
int ret;
// pictures==NXReadDefault( "Background", "Image");
if (s=NXMapFile(defaultfile, NX_READONLY)) {
while (NXScanf(s, " %255[^ \n=]%1[ \n]", p, f)==2) [self loadImageNamed:p];
ret = 1;
while (ret && (ret=NXScanf(s," = \"%255[^\n\"]\" ", f))!=EOF) {
// printf("Default read: %s = %s.\n", p, f);
if (strncmp(p, "rep", 3)==0) [self setRepeatValue:atof(f)];
else printf("Illegal default in %s: %s=%s.\n", defaultfile, p, f);
ret=NXScanf(s," %255[^=\n] ", p);
}
NXCloseMemory(s, NX_FREEBUFFER);
[self setImage:0];
} else {
fprintf(stderr, "Could not read from %s - creating it.\n", defaultfile);
temp = fopen(defaultfile, "w");
fclose(temp);
}
return self;
}
- writeDefault
{
int i;
NXStream *s;
s = NXOpenMemory(NULL, 0, NX_WRITEONLY) ;
for (i=0; i<imageCount; i++) NXPrintf(s,"%s ",imageNames[i]);
NXPrintf(s, " \nrepeat=\"%g\"\n", repeat);
if (NXSaveToFile(s, defaultfile)<0) {
printf("Could not write to %s.\n", defaultfile);
exit(1);
}
NXCloseMemory(s, NX_FREEBUFFER);
// NXWriteDefault( "Background", "Image", p); // Crashes default database
return self;
}
//
- mouseDown:(NXEvent *)event
{
PSsetwindowlevel( -1, [window windowNum]);
[window orderWindow:NX_ABOVE relativeTo:0];
[window removeFromEventMask:NX_MOUSEDOWNMASK];
return self;
}
- (BOOL)acceptsFirstMouse
{
return YES;
}
- drawSelf:(NXRect *)r :(int)count
{
PSsetgray( NX_DKGRAY);
NXRectFill( &bounds);
if (permanent) { printf("Making permanent.\n"); PSputback(); }
if(imageCount) {
int i;
NXSize s;
NXSize screenSize;
NXPoint p={ 0, 0};
NXRect r={ p};
[NXApp getScreenSize:&screenSize];
[images[current] getSize:&s];
r.size=s;
// printf("Drawing image %s: [%g,%g].\n",imageNames[current],s.width,s.height);
if (s.width>0 && s.height>0) {
[images[current] composite:NX_COPY toPoint:&p];
for( i=s.width; i<screenSize.width; i+=s.width) {
p.x=i;
PSsplat( &r, &p);
}
p.x=0;
r.size.width=screenSize.width;
for( i=s.height; i<screenSize.height; i+=s.height) {
p.y=i;
PSsplat( &r, &p);
}
}
}
return self;
}
//
- windowDidBecomeKey:sender
{
PSsetwindowlevel( NX_DOCKLEVEL+1, [sender windowNum]);
return self;
}
@end